﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ModeloGaleriaNET;
using CADs;
using AvalonDock;
using System.ComponentModel;
using Spring.Messaging.Nms.Core;
using Apache.NMS.ActiveMQ;
using Apache.NMS.ActiveMQ.Commands;
using System.Threading;
using System.Net;
using System.Web.Services.Protocols;
using SeguridadGaleria;
using ModeloGaleriaNET.Police;
using Newtonsoft.Json;
using ModeloGaleriaNET.SubastasQueries;
using ModeloGaleriaNET.SubastasQueries_Safe;
using Newtonsoft.Json.Linq;

namespace GaleriaNET
{
    delegate void CallBackgroundWorker();
    delegate void ThreadInteraction();
    public partial class ucSubastaPujaData : UserControl
    {
        #region Atributos de la clase
        private string[] permisos = new string[] { TiposRoles.VISUALIZAR_SUBASTA,
            TiposRoles.CANCELAR_SUBASTA, TiposRoles.MODIFICAR_DATOS_SUBASTA, 
       TiposRoles.FINALIZAR_SUBASTA,
        TiposRoles.PUJAR,TiposRoles.VER_LISTADO_PUJAS};

        private ModeloGaleriaNET.Police.GandalfService policia;
        private int pageSize = 10;
        private Subasta subasta;
        private bool loaded;
        private readonly string title;
        private SubastaCAD sCAD;
        private bool? originalChecked;
        private DateTime originalFecha;
        private int? originalMax;
        private bool participando;
        private string ganadorSubasta;
        private int numPujasRealizadas;
        private ModeloGaleriaNET.SubastasQueries.PujaProxy pujaGanadora;
        private int numPujas;
        private int pagenum;

        /// <summary>
        /// Pide siempre la subasta en segundo plano y comprueba (y actualiza si necesario) los datos
        /// </summary>
        private BackgroundWorker workerComprobacion, workerPermisos;
        /// <summary>
        /// Indica si la petición en segundo plano se ha realizado con éxito
        /// </summary>
        private bool peticionCorrecta;
        /// <summary>
        /// Indica si ha habido cambios
        /// </summary>
        private bool cambiosRealizados;
        /// <summary>
        /// Pujas realizadas en esta subasta validadas con el servidor
        /// </summary>
        private List<DataGridPuja> pujasSource;

        private Dictionary<string, bool> permisosDatos;

        private System.Timers.Timer timerActualizacion;

        private IAuditoria auditoria;
        #endregion

        public ucSubastaPujaData()
        {
            InitializeComponent();
            subasta = null;
            title = "Datos de la subasta";
            loaded = false;
            sCAD = null;
            Init();
        }

        public ucSubastaPujaData(Subasta s)
        {
            InitializeComponent();
            title = "Datos de la subasta";
            subasta = s;
            loaded = false;
            sCAD = null;
            Init();
        }

        public SubastaCAD SubastaCAD
        {
            set { sCAD = value; }
        }

        public string Title
        {
            get { return title; }
        }

        private void Init()
        {
            policia = new ModeloGaleriaNET.Police.GandalfService();
            policia.Timeout = (int)ModeloGaleriaNET.Properties.Settings.Default.TimeOut * 1000;
            auditoria = new AuditoriaBD();
            pujasSource = new List<DataGridPuja>();
            participando = false;
            workerComprobacion = new BackgroundWorker();
            workerComprobacion.DoWork += workerComprobacion_DoWork;
            workerComprobacion.RunWorkerCompleted += workerComprobacion_RunWorkerCompleted;
            timerActualizacion = new System.Timers.Timer(120000);
            timerActualizacion.Enabled = true;
            timerActualizacion.Elapsed += actualizacionTimer_CallBack;
            workerPermisos = new BackgroundWorker();
            workerPermisos.DoWork += workerPermisos_DoWork;
            workerPermisos.RunWorkerCompleted += workerPermisos_RunWorkerCompleted;
            pagenum = 0;
        }

        private void SetVariableFields()
        {
            TimeSpan restante;

            tbEstadoSubasta.Text = subasta.EstadoAsString;
            dtpFechaFin.Value = originalFecha = subasta.FechaLimite.ToLocalTime();
            
            if (subasta.EstadoActual.Estado.Equals("creada") || subasta.EstadoActual.Estado.Equals("publicada")
                || subasta.EstadoActual.Estado.Equals("activa"))
            {
                restante = (subasta.FechaLimite.ToLocalTime() - DateTime.Now);
                tbTiempoRestante.Text = (int)restante.TotalHours < 10 ? "0" + ((int)restante.TotalHours).ToString() : ((int)restante.TotalHours).ToString();
                tbTiempoRestante.Text += restante.Minutes < 10 ? " horas, 0" + restante.Minutes.ToString() : " horas, " + restante.Minutes.ToString();
                tbTiempoRestante.Text += restante.Seconds < 10 ? " minutos, 0" + restante.Seconds.ToString() + " segundos" : " minutos, " + restante.Seconds.ToString() + " segundos";
            }
            else if (subasta.EstadoActual.Estado.Equals("finalizada") || subasta.EstadoActual.Estado.Equals("confirmada"))
            {
                lbTiempoRestante.Content = "Ganador:";
                lbPujaMaxima.Content = "Puja ganadora:";
                tbTiempoRestante.Text = "Esta subasta ha finalizado. El ganador es " + ganadorSubasta;

                if (pujaGanadora != null)
                    tbPujaMaxima.Text = "La puja ganadora es la puja con referencia externa " + pujaGanadora.numero + ", con importe " + pujaGanadora.cantidad + " €.";
            }
            else if (subasta.EstadoActual.Estado.Equals("cancelada"))
                tbTiempoRestante.Text = "Esta subasta ha sido cancelada. Póngase en contacto con el administrador para saber las causas";

            originalChecked = cbMaximoPujas.IsChecked = !(subasta.MaximoPujasPostor == Int32.MaxValue);
            originalMax = iudMaximoPujas.Value = cbMaximoPujas.IsChecked == true ? (int?)subasta.MaximoPujasPostor : null;
        }

        private void actualizacionTimer_CallBack(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (ManejadorRoles.Instance.CanUse(TiposRoles.VISUALIZAR_SUBASTA, GetContainerWindow().Usuario.PseudonimoLocal) == true
                && ManejadorRoles.Instance.CanUse(TiposRoles.VER_LISTADO_PUJAS, GetContainerWindow().Usuario.PseudonimoLocal) == true)
            {
                if (!workerComprobacion.IsBusy)
                {
                    Dispatcher.Invoke((CallBackgroundWorker)delegate()
                    {
                        dgPujas.ItemsSource = null;
                        dgPujas.Items.Clear();
                        pujasSource.Clear();
                        pagenum = 0;
                        _busyIndicator.IsBusy = true;
                    }, null);
                    numPujasRealizadas = 0;
                    workerComprobacion.RunWorkerAsync();
                }
            }
            else
            {
                Dispatcher.Invoke((CallBackgroundWorker)delegate()
                {
                    timerActualizacion.Enabled = false;
                }, null);
            }
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            if (!loaded)
            {
                dgPujas.Columns.Add(FindResource("resColumnaImg") as DataGridTemplateColumn);
                dgPujas.Columns.Add(FindResource("resColumnaImgPropia") as DataGridTemplateColumn);
                dtpFechaFin.FormatString = "dd MMMM yyyy, HH:mm:ss";
                dtpFechaIni.FormatString = "dd MMMM yyyy, HH:mm:ss";
                tbObra.Text = subasta.NombreObra;
                tbAnyoObra.Text = subasta.AnyoFormatoObra;
                tbAutorObra.Text = subasta.AutorObra;
                tbEstadoObra.Text = subasta.EstadoObraAsString;
                dtpFechaIni.Value = subasta.FechaInicio.ToLocalTime();
                SetVariableFields();
                showButtons();

                _busyIndicator.IsBusy = true;
                numPujasRealizadas = 0;
                workerPermisos.RunWorkerAsync();
                System.Threading.Thread.Sleep(500);
                workerComprobacion.RunWorkerAsync();
                loaded = true;
            }
        }

        private SubastaProxy FromSafeToProxy(subasta sp)
        {           
            SubastaProxy salida;
   
            salida = new SubastaProxy()
            {
                añoObra = sp.obra.año,
                autorObra = sp.obra.autor,
                estado = sp.estado,
                estadoConservacionObra = sp.obra.estadoConservacion,
                fechaFin = sp.finaliza,
                fechaInicio = sp.comienza,
                ganador = sp.ganador,
                mpp = sp.mpp,
                negociado = sp.negociado,
                precioPartida = sp.precioPartida,
                propietario = sp.propietario,
                pujaGanadora = sp.pujaGanadora == null ? null : FromPujaSafeToProxy(sp.pujaGanadora),
                pujaMaxima = sp.pujaMaxima,
                pujas = sp.pujas == null ? null : FromPujaSafeToProxy(sp.pujas),
                referencia = sp.referencia,
                referenciaExterna = sp.referenciaCliente,
                tematicas = sp.tematicas,
                tituloObra = sp.obra.titulo
            };
            
            return salida;
        }

        private PujaProxy FromPujaSafeToProxy(puja puja)
        {
            PujaProxy salida;

            salida = new PujaProxy()
            {
                cantidad = puja.cantidad,
                fecha = puja.realizada,
                numero = puja.numero,
                numeroExterno = puja.numeroCliente,
                postor = puja.postor,
                referencia = puja.subasta
            };
            return salida;
        }

        private PujaProxy[] FromPujaSafeToProxy(puja[] pujas)
        {
            List<PujaProxy> salidaLista;

            salidaLista = new List<PujaProxy>();
            foreach (puja p in pujas)
                salidaLista.Add(FromPujaSafeToProxy(p));
            return salidaLista.ToArray();
        }

        private DateTime FromJSONToDate(JToken objeto)
        {
            Dictionary<string, object> fechaDic;
            object year, month, day, hour, minute, second;

            fechaDic = JsonConvert.DeserializeObject<Dictionary<string, object>>(objeto.ToString());
            fechaDic.TryGetValue("year", out year);
            fechaDic.TryGetValue("month", out month);
            fechaDic.TryGetValue("dayOfMonth", out day);
            fechaDic.TryGetValue("hourOfDay", out hour);
            fechaDic.TryGetValue("minute", out minute);
            fechaDic.TryGetValue("second", out second);

            return new DateTime(Convert.ToInt32(year), Convert.ToInt32(month) + 1, Convert.ToInt32(day), Convert.ToInt32(hour), Convert.ToInt32(minute), Convert.ToInt32(second));
        }

        private ModeloGaleriaNET.SubastasQueries_Safe.obra FromJSONToObraSafe(JToken objeto)
        {
            Dictionary<string, object> obraDic;
            object title, author, year, estado;
            ModeloGaleriaNET.SubastasQueries_Safe.obra salida;

            obraDic = JsonConvert.DeserializeObject<Dictionary<String, object>>(objeto.ToString());
            obraDic.TryGetValue("titulo", out title);
            obraDic.TryGetValue("autor", out author);
            obraDic.TryGetValue("año", out year);
            obraDic.TryGetValue("estadoConservacion", out estado);

            salida = new obra()
            {
                año = Convert.ToInt16(year),
                autor = author.ToString(),
                estadoConservacion = Convert.ToInt32(estado),
                titulo = title.ToString()
            };

            return salida;
        }

        private subasta FromJSONToSubastaSafe(JToken objeto)
        {
            ModeloGaleriaNET.SubastasQueries_Safe.subasta salida;

            salida = new ModeloGaleriaNET.SubastasQueries_Safe.subasta()
            {
                comienza = FromJSONToDate(objeto["comienza"]),
                estado = Convert.ToInt32(objeto["estado"].ToString()),
                finaliza = FromJSONToDate(objeto["finaliza"]),
                ganador = objeto["ganador"] == null ? null : objeto["ganador"].ToString(),
                mpp = Convert.ToInt32(objeto["mpp"].ToString()),
                negociado = Convert.ToInt32(objeto["negociado"].ToString()),
                obra = FromJSONToObraSafe(objeto["obra"]),
                precioPartida = Convert.ToDouble(objeto["precioPartida"].ToString()),
                propietario = objeto["propietario"].ToString(),
                pujaMaxima = Convert.ToDouble(objeto["pujaMaxima"].ToString()),
                referencia = Convert.ToInt64(objeto["referencia"].ToString()),
                tematicas = objeto["tematicas"] == null ? null : FromJSONToTematicas((JArray)objeto["tematicas"]),
                pujaGanadora = objeto["pujaGanadora"] == null ? null : FromJSONToPujaSafe(objeto["pujaGanadora"]),
                pujas = objeto["pujas"] == null ? null : FromJSONToPujaSafe((JArray)objeto["pujas"])
            };

            return salida;
        }

        private subasta[] FromJSONToSubastaSafe(JArray array)
        {
            List<ModeloGaleriaNET.SubastasQueries_Safe.subasta> salidaList;

            salidaList = new List<ModeloGaleriaNET.SubastasQueries_Safe.subasta>();
            for (int i = 0; i < array.Count; i++)
                salidaList.Add(FromJSONToSubastaSafe(array[i]));
            return salidaList.ToArray();
        }

        private puja FromJSONToPujaSafe(JToken objeto)
        {
            puja salida;

            salida = new puja()
            {
                cantidad = Convert.ToDouble(objeto["cantidad"].ToString()),
                numero = Convert.ToInt64(objeto["numero"].ToString()),
                numeroCliente = objeto["numeroCliente"].ToString(),
                postor = objeto["postor"].ToString(),
                realizada = FromJSONToDate(objeto["realizada"]),
                subasta = Convert.ToInt64(objeto["subasta"].ToString())
            };
            return salida;
        }

        private puja[] FromJSONToPujaSafe(JArray array)
        {
            List<puja> salidaList;

            salidaList = new List<puja>();
            for (int i = 0; i < array.Count; i++)
                salidaList.Add(FromJSONToPujaSafe(array[i]));
            return salidaList.ToArray();
        }

        private string[] FromJSONToTematicas(JArray array)
        {
            List<string> tematicasList;

            tematicasList = new List<string>();
            for (int i = 0; i < array.Count; i++)
                tematicasList.Add((string)array[i]);

            return tematicasList.ToArray();
        }

        private void comprobarActualizacion()
        {
            SubastasQueries querySubasta;
            SubastasQueriesService querySubastaSafe;
            AuthInfo auth;
            SubastaProxy[] participadas;
            SubastaProxy subastaPedida;
            PujaProxy[] pujasDeOtro, pujasNuestras;
            EstadoSubasta estado;
            DataGridPuja pujaGrid;
            int estadoMiSubasta;
            TematicaCAD tCAD;
            Tematica t;
            Puja pj;
            List<Puja> noAceptadas;
            authInfo authPolice;
            getTicketResponse ticketResponse;
            AESCripto aes;
            dynamic objeto;
            string json, jsonRespuesta;
            byte[] encriptado, respuesta;
            subasta[] participadasSafe;
            List<SubastaProxy> lista;
            ticketEncryptedRequest request;

            if (subasta != null && !string.IsNullOrWhiteSpace(subasta.ReferenciaExterna))
            {
                cambiosRealizados = false;
                querySubastaSafe = new SubastasQueriesService();
                querySubastaSafe.Timeout = (int)ServerConnData.Instance.TimeOut * 1000;
                querySubasta = new ModeloGaleriaNET.SubastasQueries.SubastasQueries();
                querySubasta.Timeout = (int)ServerConnData.Instance.TimeOut*1000;

                // Comprobamos si estamos participando en la subasta
                if (ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 || ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 3)
                {
                    json = "{\"filter\":\"participadas\",\"ticketId\":null}";
                    request = new ticketEncryptedRequest();

                    querySubastaSafe.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_Safe_SubastasQueriesService :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_Safe_SubastasQueriesService_SSL;
                    policia.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService_SSL;
                    authPolice = new authInfo();
                    authPolice.pseudonimo = ServerConnData.Instance.User;
                    authPolice.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
                    ticketResponse = policia.getTicket(authPolice);

                    // Crear mensaje encriptado con el JSON y enviar
                    aes = new AESCripto(ticketResponse.secretKey);
                    encriptado = aes.EncryptStringToBytes(json);

                    // Llamada al servicio web seguro ----------------->
                    request.ticketId = ticketResponse.ticketId;
                    request.message = encriptado;
                    respuesta = querySubastaSafe.listarSubastasEncrypted(request);
                    jsonRespuesta = aes.DecryptStringFromBytes(respuesta);

                    if ((JObject.Parse(jsonRespuesta))["subastas"] != null)
                    {
                        participadasSafe = FromJSONToSubastaSafe((JArray)((JObject.Parse(jsonRespuesta))["subastas"]));
                        lista = new List<SubastaProxy>();
                        foreach (subasta sp in participadasSafe)
                            lista.Add(FromSafeToProxy(sp));
                        participadas = lista.Where(subs => subs.referencia == Convert.ToInt64(subasta.ReferenciaExterna)).ToArray();
                    }
                    else
                        participadas = null;
                }
                else
                {
                    auth = new AuthInfo();
                    auth.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
                    auth.pseudonimo = ServerConnData.Instance.User;
                    querySubasta.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 0 ? 
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_SubastasQueries :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_SubastasQueries_SSL;
                    participadas = querySubasta.listarParticipadasPorUsuario(auth).Where(subs => subs.referencia == Convert.ToInt64(subasta.ReferenciaExterna)).ToArray();
                }
                participando = (participadas != null && participadas.Count() > 0);

                if (participando)
                    GestorMensajes.Instance.deleteMessageMQ(Convert.ToInt64(subasta.ReferenciaExterna));
                // Fin de la comprobación de si estamos participando en la subasta

                if (ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 || ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 3)
                {
                    // Encriptar cosas en JSON
                    objeto = new 
                    { 
                        referencia = Convert.ToInt64(subasta.ReferenciaExterna) 
                    };
                    json = JsonConvert.SerializeObject(objeto);
                    // Fin encriptar cosas en JSON

                    querySubastaSafe.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_Safe_SubastasQueriesService :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_Safe_SubastasQueriesService_SSL;
                    policia.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 2 ?
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_Police_GandalfService_SSL;
                    authPolice = new authInfo();
                    authPolice.pseudonimo = ServerConnData.Instance.User;
                    authPolice.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
                    ticketResponse = policia.getTicket(authPolice);

                    // Crear mensaje encriptado con el JSON y enviar
                    aes = new AESCripto(ticketResponse.secretKey);
                    encriptado = aes.EncryptStringToBytes(json);

                    // Llamada al servicio web seguro ----------------->
                    request = new ticketEncryptedRequest();
                    request.ticketId = ticketResponse.ticketId;
                    request.message = encriptado;
                    respuesta = querySubastaSafe.mostrarSubastaEncrypted(request);
                    jsonRespuesta = aes.DecryptStringFromBytes(respuesta);

                    subastaPedida = FromSafeToProxy(FromJSONToSubastaSafe(JObject.Parse(jsonRespuesta)));
                }
                else
                {
                    auth = new AuthInfo();
                    auth.password = Utilities.EncriptarMD5(ServerConnData.Instance.Password);
                    auth.pseudonimo = ServerConnData.Instance.User;
                    // Comprobación de los datos de la subasta
                    querySubasta.Url = ModeloGaleriaNET.Properties.Settings.Default.Seguridad == 0 ?
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_SubastasQueries :
                        ModeloGaleriaNET.Properties.Settings.Default.ModeloGaleriaNET_SubastasQueries_SubastasQueries_SSL;
                    subastaPedida = querySubasta.mostrar(auth, Convert.ToInt64(subasta.ReferenciaExterna), true);
                }
                
                if (subastaPedida != null)
                {
                    tCAD = new TematicaCAD();
                    #region Comprobar validez de mis pujas (modificar para ver todas las pujas)
                    // ---------------------------------------------------------------------------->
                    if (subastaPedida.pujas != null && subastaPedida.pujas.Count() > 0)
                    {
                        // Primero validamos nuestras pujas
                        pujasNuestras = subastaPedida.pujas.Where(pn => pn.postor.Equals(ServerConnData.Instance.User)).ToArray();
                        if (pujasNuestras != null && pujasNuestras.Count() > 0)
                        {
                            foreach (PujaProxy pdo in pujasNuestras)
                            {
                                pj = subasta.Pujas.Where(pjj => pjj.Id.ToString().Equals(pdo.numeroExterno)).First();

                                if (pj.IdCore > 0)
                                {
                                    pujaGrid = new DataGridPuja(pj.Id, pj.IdCore.ToString(), ServerConnData.Instance.User, pj.Fecha.ToLocalTime(), pj.Cantidad, DataGridPuja.TIPO_MENSAJE.INFO, true);
                                    numPujasRealizadas++;
                                }
                                else
                                {
                                    pj.IdCore = (int)pdo.numero;
                                    pujaGrid = new DataGridPuja(pj.Id, pj.IdCore.ToString(), ServerConnData.Instance.User, pj.Fecha.ToLocalTime(), pj.Cantidad, DataGridPuja.TIPO_MENSAJE.INFO, true);
                                    numPujasRealizadas++;
                                }

                               pujasSource.Add(pujaGrid);
                            }
                        }
                        noAceptadas = subasta.Pujas.Where(pjj => pjj.IdCore <= 0).ToList();
                        if (noAceptadas != null && noAceptadas.Count > 0)
                        {
                            foreach(Puja pjj in noAceptadas)
                            {
                                pujaGrid = new DataGridPuja(pjj.Id, string.Empty, ServerConnData.Instance.User, pjj.Fecha.ToLocalTime(), pjj.Cantidad, DataGridPuja.TIPO_MENSAJE.ERROR, true);
                                pujasSource.Add(pujaGrid);
                            }
                        }

                        // A continuación, validamos las pujas de otros
                        pujasDeOtro = subastaPedida.pujas.Where(pdo => !pdo.postor.Equals(ServerConnData.Instance.User)).ToArray();
                        if (pujasDeOtro != null && pujasDeOtro.Count() > 0)
                        {
                            foreach (PujaProxy pdo in pujasDeOtro)
                            {
                                pujaGrid = new DataGridPuja(Convert.ToInt32(pdo.numeroExterno), pdo.numero.ToString(), pdo.postor, pdo.fecha.Value, pdo.cantidad, DataGridPuja.TIPO_MENSAJE.INFO, false);
                                pujasSource.Add(pujaGrid);
                            }
                        }
                        pujasSource = pujasSource.OrderByDescending(ps => ps.FechaAsDate).ToList();
                        numPujas = pujasSource.Count;
                    }
                    // -------------------------------------------------------------------------->
                    #endregion

                    #region Comprobación de cambios en la subasta
                    if (subasta.Tematicas == null || subasta.Tematicas.Count == 0)
                    {
                        foreach (string tem in subastaPedida.tematicas)
                        {
                            t = tCAD.GetTematicaByNombre(tem);
                            if (t != null)
                                subasta.Tematicas.Add(t);
                        }
                    }

                    estadoMiSubasta = subasta.EstadoActual.Estado.Equals("publicada") ? 0 :
                        subasta.EstadoActual.Estado.Equals("activa") ? 1 :
                        subasta.EstadoActual.Estado.Equals("finalizada") ? 2 :
                        subasta.EstadoActual.Estado.Equals("confirmada") ? 3 :
                        subasta.EstadoActual.Estado.Equals("cancelada") ? 4 :
                        subasta.EstadoActual.Estado.Equals("creada") ? 5 : -1;

                    // Obtención de la puja máxima o, en caso de no haber, del precio de partida
                    if (subastaPedida.pujas == null || subastaPedida.pujas.Count() <= 0 || subastaPedida.pujaMaxima == 0.0)
                        subasta.PrecioPartida = subastaPedida.precioPartida;
                    else
                        subasta.PrecioPartida = subastaPedida.pujaMaxima;

                    if (estadoMiSubasta != subastaPedida.estado || subastaPedida.mpp != subasta.MaximoPujasPostor
                            || subastaPedida.fechaFin.Value != subasta.FechaLimite)
                    {
                        // El estado ha cambiado, hay que buscar el nuevo
                        if (estadoMiSubasta != subastaPedida.estado)
                        {
                            estadoMiSubasta = subastaPedida.estado;
                            estado = estadoMiSubasta == 0 ? new EstadoSubastaCAD().GetEstadoPublicada() :
                                estadoMiSubasta == 1 ? new EstadoSubastaCAD().GetEstadoActiva() :
                                estadoMiSubasta == 2 ? new EstadoSubastaCAD().GetEstadoFinalizada() :
                                estadoMiSubasta == 3 ? new EstadoSubastaCAD().GetEstadoConfirmada() :
                                estadoMiSubasta == 4 ? new EstadoSubastaCAD().GetEstadoCancelada() : null;
                            subasta.ChangeState(estado);
                        }

                        // MPP
                        if (subastaPedida.mpp != subasta.MaximoPujasPostor)
                            subasta.MaximoPujasPostor = subastaPedida.mpp;

                        // Fecha
                        if (subastaPedida.fechaFin.Value.ToUniversalTime() != subasta.FechaLimite)
                            subasta.FechaLimite = subastaPedida.fechaFin.Value.ToUniversalTime();

                        cambiosRealizados = true;
                    }

                    if (subastaPedida.estado == 3 || subastaPedida.estado == 2) // Confirmada o finalizada
                    {
                        ganadorSubasta = subastaPedida.ganador;
                        pujaGanadora = subastaPedida.pujaGanadora;
                        if (subastaPedida.estado == 3)
                        {
                            if (subasta.IsSubastaPropia && subasta.ClientesPropietariosObras.FechaFin == null)
                                subasta.ClientesPropietariosObras.FechaFin = DateTime.UtcNow;
                        }
                    }
                    
                    sCAD.SaveChanges();
                    #endregion
                }
                // Fin de comprobación de los datos de la subasta
            }
            else
                throw new SubastaNotInServerException();
        }

        private void workerComprobacion_DoWork(object sender, DoWorkEventArgs e)
        {
            int intentos = 0;

            while (workerPermisos.IsBusy)
            {
            }

            if (!(permisosDatos != null && permisosDatos.Count == permisos.Length))
            {
                peticionCorrecta = false;
                return;
            }

            while (true)
            {
                try
                {
                    comprobarActualizacion();
                    peticionCorrecta = true;
                    break;
                }
                catch (SubastaNotInServerException)
                {
                    peticionCorrecta = false;
                    break;
                }
                catch (WebException)
                {
                    intentos++;
                    if (intentos == 3)
                        break;
                    jUDDIManager.Instance.UpdateURL();
                }
                catch (SoapException ex)
                {
                    if (ex.Message.Equals("Pseudónimo o contraseña incorrectos."))
                    {
                        Utilities.WriteMessageOnGrid(GetContainerWindow().salidaDataGrid,
                            "Usuario o contraseña del servidor incorrectos", DataGridMessage.TIPO_MENSAJE.ERROR);
                        break;
                    }
                    intentos++;
                    if (intentos == 3)
                    {
                        peticionCorrecta = false;
                        break;
                    }
                }
                catch (Exception)
                {
                    intentos++;
                    if (intentos == 3)
                    {
                        peticionCorrecta = false;
                        break;
                    }
                }
            }
        }

        private void workerComprobacion_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ucSubastas subs;
            DocumentContent padre;

            Dispatcher.Invoke((ThreadInteraction)delegate()
            {
                _busyIndicator.IsBusy = false;
                if (peticionCorrecta)
                {
                    SetDataGridSource();
                    tbPujaMaxima.Text = subasta.PrecioPartida + " €";
                    
                    if (cambiosRealizados)
                    {
                        showButtons();
                        if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                        {
                            subs = (ucSubastas)(padre.Content);
                            subs.ActualizarDataGrid();
                        }
                    }
                    SetVariableFields();
                }
            }, null);
        }

        private void workerPermisos_DoWork(object sender, DoWorkEventArgs e)
        {
            bool? value;
            string usuario;

            usuario = Convert.ToString(Utilities.FindUsuarioData(typeof(UserWindow), this, "Name"));
            permisosDatos = new Dictionary<string, bool>();
            foreach (string s in permisos)
            {
                value = ManejadorRoles.Instance.CanUse(s, usuario);
                if (value != null)
                    permisosDatos.Add(s, value.Value);
            }
        }

        private void workerPermisos_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bool value;

            if (!(permisosDatos != null && permisosDatos.Count == permisos.Length))
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se han podido obtener todos los permisos", "Error",
                    MessageBoxButton.OK, MessageBoxImage.Error);
                btActualizar.IsEnabled = btAnterior.IsEnabled = btCancelarActivaPropia.IsEnabled = btCancelarCreada.IsEnabled =
                    btCancelarPublicada.IsEnabled = btFinalizarActivaPropia.IsEnabled = btGuardarCambiosActivaPropia.IsEnabled =
                    btGuardarCreada.IsEnabled = btGuardarPublicadaPropia.IsEnabled = btParticiparNO.IsEnabled = btParticiparPropia.IsEnabled =
                    btPublicar.IsEnabled = btPujarActivaNO.IsEnabled = btPujarActivaPropia.IsEnabled = btRechazarNO.IsEnabled =
                    btRechazarPropia.IsEnabled = btSiguiente.IsEnabled = false;
                timerActualizacion.Enabled = false;
                dtpFechaFin.IsEnabled = cbMaximoPujas.IsEnabled = iudMaximoPujas.IsEnabled = false;
            }
            else
            {
                // Pujar
                permisosDatos.TryGetValue(TiposRoles.PUJAR, out value);
                if (!value)
                    btPujarActivaNO.IsEnabled = btPujarActivaPropia.IsEnabled = false;
    
                // Finalizar subasta
                permisosDatos.TryGetValue(TiposRoles.FINALIZAR_SUBASTA, out value);
                if (!value)
                    btFinalizarActivaPropia.IsEnabled = false;

                // Modificar subasta
                permisosDatos.TryGetValue(TiposRoles.MODIFICAR_DATOS_SUBASTA, out value);
                if (!value)
                    btGuardarCambiosActivaPropia.IsEnabled = btGuardarCreada.IsEnabled = btGuardarPublicadaPropia.IsEnabled =
                        dtpFechaFin.IsEnabled = cbMaximoPujas.IsEnabled = iudMaximoPujas.IsEnabled = false;

                // Cancelar subasta
                permisosDatos.TryGetValue(TiposRoles.CANCELAR_SUBASTA, out value);
                if (!value)
                    btCancelarActivaPropia.IsEnabled = btCancelarCreada.IsEnabled = btCancelarPublicada.IsEnabled = false;    
            }
        }

        private void Close()
        {
            ((DocumentContent)this.Parent).Close();
        }

        private void ClosingDocument(object sender, CancelEventArgs e)
        {
            if (HasChanges())
            {
                if (MessageBox.Show("¿Desea salir sin aplicar los cambios?", "Salir",
                    MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                    e.Cancel = true;
                else
                {
                    timerActualizacion.Stop();
                }
            }
        }

        private bool HasChanges()
        {
            if (originalFecha != dtpFechaFin.Value || originalChecked != cbMaximoPujas.IsChecked || originalMax != iudMaximoPujas.Value)
                return true;
            return false;
        }

        public void AddEventHandler()
        {
            ((DocumentContent)this.Parent).Closing += ClosingDocument;
        }

        private DocumentContent FindDocumentContent(Type t)
        {
            DockingManager manager;

            manager = ((DocumentContent)this.Parent).Manager;
            // Buscamos si hay abierta una instancia del documento a abrir
            foreach (AvalonDock.DocumentContent doc in manager.Documents)
            {
                if (doc.Content.GetType() == t)
                    return doc;
            }
            return null;
        }

        private UserWindow GetContainerWindow()
        {
            DockingManager manager;
            manager = ((DocumentContent)(this.Parent)).Manager;
            return (UserWindow)(((Grid)(manager.Parent)).Parent);
        }

        private void ParametrosCambiados()
        {
            if (originalChecked != cbMaximoPujas.IsChecked ||
                originalFecha != dtpFechaFin.Value ||
                originalMax != iudMaximoPujas.Value)
            {
                if (gridBotonesCreada.Visibility == Visibility.Visible)
                    btGuardarCreada.IsEnabled = true;
                else if (gridBotonesActivaPropia.Visibility == Visibility.Visible)
                    btGuardarCambiosActivaPropia.IsEnabled = true;
                else if (gridBotonesPublicadaPropia.Visibility == Visibility.Visible)
                    btGuardarPublicadaPropia.IsEnabled = true;
            }
            else
            {
                if (gridBotonesCreada.Visibility == Visibility.Visible)
                    btGuardarCreada.IsEnabled = false;
                else if (gridBotonesActivaPropia.Visibility == Visibility.Visible)
                    btGuardarCambiosActivaPropia.IsEnabled = false;
                else if (gridBotonesPublicadaPropia.Visibility == Visibility.Visible)
                    btGuardarPublicadaPropia.IsEnabled = false;
            }
        }

        private void showButtons()
        {
            gridBotonesActivaNO.Visibility = gridBotonesActivaPropia.Visibility = gridBotonesCreada.Visibility =
                gridBotonesFinalizada.Visibility = gridBotonesPublicadaNO.Visibility = gridBotonesPublicadaPropia.Visibility = Visibility.Collapsed;

            // El primer TabIndex que toca es el 11
            if (subasta.EstadoActual.Estado.Equals("cancelada") || subasta.EstadoActual.Estado.Equals("confirmada") ||
                    subasta.EstadoActual.Estado.Equals("finalizada"))
            {
                dtpFechaFin.IsEnabled = cbMaximoPujas.IsEnabled = iudMaximoPujas.IsEnabled = false;
                gridBotonesFinalizada.Visibility = Visibility.Visible;
                btSalirFinalizada.IsCancel = true;
                btSalirFinalizada.TabIndex = 11;
            }
            else if (subasta.EstadoActual.Estado.Equals("creada"))
            {
                gridBotonesCreada.Visibility = Visibility.Visible;
                btSalirCreada.IsCancel = true;
                btPublicar.IsDefault = true;
                btPublicar.TabIndex = 11;
                btSalirCreada.TabIndex = 12;
            }
            else if (subasta.EstadoActual.Estado.Equals("publicada"))
            {
                if (subasta.IsSubastaPropia)
                {
                    gridBotonesPublicadaPropia.Visibility = Visibility.Visible;
                    btSalirPublicadaPropia.IsCancel = true;
                    btParticiparPropia.IsDefault = true;
                    btParticiparPropia.TabIndex = 11;
                    btRechazarPropia.TabIndex = 12;
                    btCancelarPublicada.TabIndex = 13;
                    btGuardarPublicadaPropia.TabIndex = 14;
                    btSalirPublicadaPropia.TabIndex = 15;

                    if (participando)
                    {
                        btRechazarPropia.IsEnabled = false;
                        btParticiparPropia.IsEnabled = false;
                    }
                }
                else
                {
                    dtpFechaFin.IsEnabled = cbMaximoPujas.IsEnabled = iudMaximoPujas.IsEnabled = false;
                    gridBotonesPublicadaNO.Visibility = Visibility.Visible;
                    btSalirPublicadaNO.IsCancel = true;
                    btParticiparNO.IsDefault = true;
                    btParticiparNO.TabIndex = 11;
                    btRechazarNO.TabIndex = 12;
                    btSalirPublicadaNO.TabIndex = 13;

                    if (participando)
                    {
                        btRechazarNO.IsEnabled = false;
                        btParticiparNO.IsEnabled = false;
                    }
                }
            }
            else if (subasta.EstadoActual.Estado.Equals("activa"))
            {
                if (subasta.IsSubastaPropia)
                {
                    gridBotonesActivaPropia.Visibility = Visibility.Visible;
                    btSalirActivaPropia.IsCancel = true;
                    btPujarActivaPropia.IsDefault = true;
                    btPujarActivaPropia.TabIndex = 11;
                    btFinalizarActivaPropia.TabIndex = 12;
                    btCancelarActivaPropia.TabIndex = 13;
                    btGuardarCambiosActivaPropia.TabIndex = 14;
                    btSalirActivaPropia.TabIndex = 15;
                    if (subasta.TipoNegociado.Equals("automatico"))
                        btFinalizarActivaPropia.Visibility = Visibility.Collapsed;
                }
                else
                {
                    dtpFechaFin.IsEnabled = cbMaximoPujas.IsEnabled = iudMaximoPujas.IsEnabled = false;
                    gridBotonesActivaNO.Visibility = Visibility.Visible;
                    btSalirActivaNO.IsCancel = true;
                    btPujarActivaNO.IsDefault = true;
                    btSalirActivaNO.TabIndex = 11;
                    btPujarActivaNO.TabIndex = 12;
                }
            }
        }

        #region Eventos de los botones de las subastas (8 acciones)

        private void btCancelarSubasta_Click(object sender, RoutedEventArgs e) // Ok
        {
            // Se pasa el estado a cancelada y se avisa de ello al servidor
            ucSubastas subastas;
            DocumentContent padre;
            CancelarSubastaMessage mensaje;

            try
            {
                // Cancelar en el servidor
                mensaje = new CancelarSubastaMessage(subasta, ((UserWindow)GetContainerWindow()).salidaDataGrid, ((UserWindow)GetContainerWindow()).Usuario.Id);
                ((UserWindow)GetContainerWindow()).AddMessage(mensaje);
                subasta.ChangeState(new EstadoSubastaCAD().GetEstadoCancelada());
                sCAD.SaveChanges();
                
                if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                {
                    subastas = (ucSubastas)(padre.Content);
                    subastas.ActualizarDataGrid();
                }
                SetVariableFields();
            }
            catch (Exception ex)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido publicar la subasta\n" + ex.Message,
                    "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void btFinalizarSubasta_Click(object sender, RoutedEventArgs e) // Ok
        {            
            FinalizarSubastaMessage mensaje;
            ChooseWinnerWindow window;
            ucSubastas subastas;
            DocumentContent padre;

            // Hay que elegir una puja ganadora y pasar el estado a finalizada
            window = new ChooseWinnerWindow(subasta);
            window.ShowDialog();

            if (window.Success)
            {
                try
                {
                    mensaje = new FinalizarSubastaMessage(subasta, window.Winner, ((UserWindow)GetContainerWindow()).salidaDataGrid, ((UserWindow)GetContainerWindow()).Usuario.Id);
                    ((UserWindow)GetContainerWindow()).AddMessage(mensaje);
                    subasta.ChangeState(new EstadoSubastaCAD().GetEstadoFinalizada());
                    sCAD.SaveChanges();

                    if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                    {
                        subastas = (ucSubastas)(padre.Content);
                        subastas.ActualizarDataGrid();
                    }

                    // Xceed.Wpf.Toolkit.MessageBox.Show("Subasta finalizada en local con éxito",
                        //   "Subasta finalizada", MessageBoxButton.OK, MessageBoxImage.Information);
                    SetVariableFields();
                }
                catch (Exception)
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido finalizar la subasta",
                        "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void btGuardarCambios_Click(object sender, RoutedEventArgs e) // Ok
        {
            ucSubastas subastas;
            DocumentContent padre;
            ModificarSubastaMessage mensaje;

            try
            {
                // Creamos el mensaje para tener la información guardada
                mensaje = new ModificarSubastaMessage(subasta, ((UserWindow)GetContainerWindow()).salidaDataGrid, ((UserWindow)GetContainerWindow()).Usuario.Id);

                if (dtpFechaFin.Value.Value.ToUniversalTime() != originalFecha)
                {
                    subasta.FechaLimite = dtpFechaFin.Value.Value.ToUniversalTime();
                    subasta.ZonaInicioFin = Utilities.GetZonaHoraria();
                }

                if (originalChecked != cbMaximoPujas.IsChecked)
                {
                    if (cbMaximoPujas.IsChecked == true)
                        subasta.MaximoPujasPostor = (int)iudMaximoPujas.Value;
                    else if (cbMaximoPujas.IsChecked == false)
                        subasta.MaximoPujasPostor = Int32.MaxValue;
                }
                else if (originalMax != iudMaximoPujas.Value)
                    subasta.MaximoPujasPostor = (int)iudMaximoPujas.Value;

                sCAD.SaveChanges();
                ((UserWindow)GetContainerWindow()).AddMessage(mensaje);

                if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                {
                    subastas = (ucSubastas)(padre.Content);
                    subastas.ActualizarDataGrid();
                }
                //Xceed.Wpf.Toolkit.MessageBox.Show("Cambios realizados en local con éxito",
                    //  "Cambios guardados", MessageBoxButton.OK, MessageBoxImage.Information);

                if (gridBotonesActivaPropia.Visibility == Visibility.Visible)
                    btGuardarCambiosActivaPropia.IsEnabled = false;
                else if (gridBotonesPublicadaPropia.Visibility == Visibility.Visible)
                    btGuardarPublicadaPropia.IsEnabled = false;
                else if (gridBotonesCreada.Visibility == Visibility.Visible)
                    btGuardarCreada.IsEnabled = false;

                SetVariableFields();
            }
            catch (Exception ex)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se han podido realizar los cambios\n" + ex.Message,
                    "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void btParticipar_Click(object sender, RoutedEventArgs e)
        {
            ActiveMQMapMessage mensaje;
            if (!participando)
            {
                // Coger los datos de la subasta recibida, guardarla como publicada y enviar suscripción
                if (subasta is SubastaDeOtro)
                    sCAD.addSubastaDeOtro((SubastaDeOtro)subasta);

                // Procesado del mensaje de la suscripción
                mensaje = new ActiveMQMapMessage();
                mensaje.Body.SetString("pseudonimo", ServerConnData.Instance.User);
                mensaje.Body.SetString("password", Utilities.EncriptarMD5(ServerConnData.Instance.Password));
                mensaje.Body.SetLong("referencia", Convert.ToInt64(subasta.ReferenciaExterna));
                mensaje.Body.SetBool("suscripcion", true);
                GetContainerWindow().AddMessageMQ(mensaje);
                auditoria.Mensaje(new object[] { subasta.Id },
                    TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.SUSCRIBIRSE), GetContainerWindow().Usuario.Id);
            }
            else
                Xceed.Wpf.Toolkit.MessageBox.Show("Ya estás participando en esta subasta. No te puedes suscribir de nuevo", 
                    "Error", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private void btPublicar_Click(object sender, RoutedEventArgs e) // Ok
        {
            ucSubastas subastas;
            DocumentContent padre;
            MessageCrearSubasta mensaje;

            try
            {
                // Fijar fecha de fin del estado "creada"
                subasta.ChangeState(new EstadoSubastaCAD().GetEstadoPublicada());
                mensaje = new MessageCrearSubasta(subasta, ((UserWindow)GetContainerWindow()).salidaDataGrid, ((UserWindow)GetContainerWindow()).Usuario.Id);
                sCAD.SaveChanges();
                GetContainerWindow().AddMessage(mensaje);
                if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucSubastas)))) != null)
                {
                    subastas = (ucSubastas)(padre.Content);
                    subastas.ActualizarDataGrid();
                }
                SetVariableFields();
                //Xceed.Wpf.Toolkit.MessageBox.Show("Subasta publicada en local con éxito",
            //    "Subasta publicada", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido publicar la subasta\n" + ex.Message,
                    "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void btPujar_Click(object sender, RoutedEventArgs e)
        {
            Puja p;
            UserWindow userwin;
            NewPujaWindow window;
            ActiveMQMapMessage mensaje;

            if (participando && numPujasRealizadas < subasta.MaximoPujasPostor)
            {
                window = new NewPujaWindow(Convert.ToDouble(tbPujaMaxima.Text.Replace("€", string.Empty).Replace(" ", string.Empty)));
                window.ShowDialog();

                if (window.Success)
                {
                    // Mandar la puja al servidor (ActiveMQ) y crearla en local
                    userwin = GetContainerWindow();
                    p = new Puja();
                    p.Subasta = subasta.Id;
                    p.Cantidad = (double)window.Valor;
                    p.UsuarioAutor = userwin.Usuario.Id;
                    p.PseudonimoAutor = userwin.Usuario.PseudonimoLocal;
                    p.Fecha = DateTime.UtcNow;
                    p.ZonaHoraria = Utilities.GetZonaHoraria();

                    if (sCAD.SavePuja(subasta, p))
                    {
                        mensaje = new ActiveMQMapMessage();
                        mensaje.Body.SetString("pseudonimo", ServerConnData.Instance.User);
                        mensaje.Body.SetString("password", Utilities.EncriptarMD5(ServerConnData.Instance.Password));
                        mensaje.Body.SetLong("referencia", Convert.ToInt64(subasta.ReferenciaExterna));
                        mensaje.Body.SetDouble("cantidad", p.Cantidad);
                        mensaje.Body.SetString("numeroExterno", p.Id.ToString());
                        mensaje.Body.SetBool("suscripcion", false);
                        GetContainerWindow().AddMessageMQ(mensaje);
                        auditoria.Mensaje(new object[] { p.Id, subasta.Id },
                            TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.PUJAR), userwin.Usuario.Id);
                    }
                    else
                        Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido realizar la puja. Ha ocurrido un error al guardarla en local",
                            "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                if (!participando)
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("No estás participando en la subasta", "Error",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("Ya has alcanzado el máximo de pujas a realizar", "Error",
                        MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
        }

        private void btRechazarClick(object sender, RoutedEventArgs e)
        {
            if (Xceed.Wpf.Toolkit.MessageBox.Show("¿Desea rechazar la participación en esta subasta?\nEsta acción no se puede deshacer",
                "Rechazar subasta", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                GestorMensajes.Instance.deleteMessageMQ(Convert.ToInt64(subasta.ReferenciaExterna));
                Close();
            }
        }

        private void btSalir_Click(object sender, RoutedEventArgs e) // Ok
        {
            if ((gridBotonesActivaPropia.Visibility == Visibility.Visible && btGuardarCambiosActivaPropia.IsEnabled) ||
                (gridBotonesCreada.Visibility == Visibility.Visible && btGuardarCreada.IsEnabled) ||
                (gridBotonesPublicadaPropia.Visibility == Visibility.Visible && btGuardarPublicadaPropia.IsEnabled))
            {
                if (Xceed.Wpf.Toolkit.MessageBox.Show("Hay cambios pendientes de guardarse, ¿desea salir?",
                    "Salir", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    Close();
                else
                    return;
            }
            else
                Close();
        }

        #endregion

        private void dtpFechaFin_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            ParametrosCambiados();
        }

        private void cbMaximoPujas_Unchecked(object sender, RoutedEventArgs e)
        {
            ParametrosCambiados();
        }

        private void cbMaximoPujas_Checked(object sender, RoutedEventArgs e)
        {
            ParametrosCambiados();
        }

        private void iudMaximoPujas_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            ParametrosCambiados();
        }

        private void btActualizar_Click(object sender, RoutedEventArgs e)
        {
            timerActualizacion.Stop();

            actualizacionTimer_CallBack(sender, null);
            SetVariableFields();
            timerActualizacion.Start();
        }

        private void btAnterior_Click(object sender, RoutedEventArgs e)
        {
            pagenum--;
            SetDataGridSource();
            UpdatePaginationControls();
        }

        private void btAnterior_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            IntPtr b;
            BitmapSource bs;

            if (imgBtAnterior != null)
            {
                b = Convert.ToBoolean(e.NewValue) ? Properties.Resources.Left_24.GetHbitmap() : Properties.Resources.LeftBW_24.GetHbitmap();
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b, IntPtr.Zero, Int32Rect.Empty,
                  System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                this.imgBtAnterior.Source = bs;
            }
        }

        private void btSiguiente_Click(object sender, RoutedEventArgs e)
        {
            pagenum++;
            SetDataGridSource();
            UpdatePaginationControls();
        }

        private void btSiguiente_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            IntPtr b;
            BitmapSource bs;

            if (imgBtSiguiente != null)
            {
                b = Convert.ToBoolean(e.NewValue) ? Properties.Resources.Right_24.GetHbitmap() : Properties.Resources.RightBW_24.GetHbitmap();
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(b, IntPtr.Zero, Int32Rect.Empty,
                  System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                this.imgBtSiguiente.Source = bs;
            }
        }

        private void SetDataGridSource()
        {
            int inicio;
            List<DataGridPuja> source;
            bool value;

            permisosDatos.TryGetValue(TiposRoles.VER_LISTADO_PUJAS, out value);

            if (value)
            {
                source = new List<DataGridPuja>();
                inicio = pagenum * pageSize;
                dgPujas.ItemsSource = null;
                dgPujas.Items.Clear();

                for (int i = inicio; i < pujasSource.Count && i < inicio + pageSize; i++)
                    source.Add(pujasSource[i]);
            }
            else
                source = new List<DataGridPuja>();
            dgPujas.ItemsSource = source;
            UpdatePaginationControls();
        }

        private void UpdatePaginationControls()
        {
            String iniString = "0";
            String deString = string.Empty;

            if (numPujas > 0)
                iniString = (pagenum * pageSize + 1).ToString();

            btAnterior.IsEnabled = pagenum == 0 ? false : true;

            if (pagenum + 1 >= numPujas / (float)pageSize)
            {
                btSiguiente.IsEnabled = false;
                deString = numPujas.ToString();
            }
            else
            {
                btSiguiente.IsEnabled = true;
                deString = ((pagenum + 1) * pageSize).ToString();
            }

            lbPagina.Content = iniString + " - " + deString + " de " + numPujas;
        }
    }
}
